﻿#include "../control.h"

namespace swui
{
	void ctlRoot::_size_change()
	{
		if(getSizeFormat(ctlDirection::x) == sizeFormat::absolute &&
			getSizeFormat(ctlDirection::y) == sizeFormat::absolute) return;
		ctlRect rect = _eventTrans.getParentRect();
		ctlPoint pt(getWidth(), getHeight());
		switch(getSizeFormat(ctlDirection::x))
		{
		case sizeFormat::percent:
			pt.x = int(rect.cx * _sizeX.frac);
			break;
		case sizeFormat::relative:
			if(getParent() == getSizeRelation(ctlDirection::x))
				pt.x = rect.cx - _sizeX.num - getLeft();
			else pt.x = getSizeRelation(ctlDirection::x)->getLeft() - _sizeX.num - getLeft();
			break;
		}
		switch(getSizeFormat(ctlDirection::y))
		{
		case sizeFormat::percent:
			pt.y = int(rect.cy * _sizeY.frac);
			break;
		case sizeFormat::relative:
			if(getParent() == getSizeRelation(ctlDirection::y))
				pt.y = rect.cy - _sizeY.num - getTop();
			else pt.y = getSizeRelation(ctlDirection::y)->getTop() - _sizeY.num - getTop();
			break;
		}
		if(pt.x != getWidth() || pt.y != getHeight())
			size(pt);
	}
	ctlPoint _get_alignment_point(ctlRoot::moveAlignment align, ctlRect rect)
	{
		ctlPoint pt;
		switch(align)
		{
			case ctlRoot::moveAlignment::leftBottom:
			case ctlRoot::moveAlignment::leftMiddle:
			case ctlRoot::moveAlignment::leftTop:
				pt.x = rect.getLeft();
				break;
			case ctlRoot::moveAlignment::middleBottom:
			case ctlRoot::moveAlignment::middle:
			case ctlRoot::moveAlignment::middleTop:
				pt.x = rect.getLeft() + rect.getWidth() / 2;
				break;
			default:
				pt.x = rect.getRight();
				break;
		}
		switch(align)
		{
			case ctlRoot::moveAlignment::leftBottom:
			case ctlRoot::moveAlignment::middleBottom:
			case ctlRoot::moveAlignment::rightBottom:
				pt.y = rect.getBottom();
				break;
			case ctlRoot::moveAlignment::middleTop:
			case ctlRoot::moveAlignment::leftTop:
			case ctlRoot::moveAlignment::rightTop:
				pt.y = rect.getTop();
				break;
			default:
				pt.y = rect.getTop() + rect.getHeight() / 2;
				break;
		}
		return pt;
	}
	ctlPoint ctlRoot::_calc_move_relative(ctlRoot* relation, ctlDirection dir)
	{
		ctlPoint thispt = _get_alignment_point(getThisMoveAlignment(), this->getRect());
		ctlPoint relationpt = _get_alignment_point(getRelationMoveAlignment(), relation->getRect());
		thispt.x -= getLeft(), thispt.y -= getTop();
		if(getParent() == relation)
			relationpt.x -= relation->getLeft(), relationpt.y -= relation->getTop();
		ctlPoint result(getLeft(), getTop());
		if((unsigned)dir & (unsigned)ctlDirection::x)
			result.x = relationpt.x + _moveX.num - thispt.x;
		if((unsigned)dir & (unsigned)ctlDirection::y)
			result.y = relationpt.y + _moveY.num - thispt.y;
		return result;
	}
	void ctlRoot::_move_change()
	{
		if(getMoveFormat(ctlDirection::x) == moveFormat::absolute && 
			getMoveFormat(ctlDirection::y) == moveFormat::absolute) return;
		ctlRect rect = _eventTrans.getParentRect();
		ctlPoint pt(getLeft(), getTop());
		switch(getMoveFormat(ctlDirection::x))
		{
		case moveFormat::percent:
			pt.x = int(rect.cx * _moveX.frac);
			break;
		case moveFormat::relative:
			pt.x = _calc_move_relative(_moveX.relation, ctlDirection::x).x;
			break;
		}
		switch(getMoveFormat(ctlDirection::y))
		{
		case moveFormat::percent:
			pt.y = int(rect.cy * _moveY.frac);
			break;
		case moveFormat::relative:
			pt.y = _calc_move_relative(_moveY.relation, ctlDirection::y).y;
			break;
		}
		if(pt.x != getLeft() || pt.y != getTop())
			move(pt);
	}
}